<template>
  <div :class="$style.wapper">
    <div :class="$style.top">
      <a-button
        type="primary"
        style="margin-left: 10px"
        @click="openModel = true"
        >发布</a-button
      >
      <div v-for="item in 3" :key="item" :class="$style.page">
        <a-tooltip placement="top">
          <template #title>
            <span>刷新列表</span>
          </template>
          <RedoOutlined :class="$style.icon" @click="refreshList(item - 1)" />
        </a-tooltip>
        <a-pagination
          v-model:current="commonData[item - 1].current"
          v-model:pageSize="commonData[item - 1].pageSize"
          :total="commonData[item - 1].total"
          show-less-items
          :show-total="total => `共 ${total} 条`"
          :show-size-changer="false"
          @change="page => handlePageChange(page, item - 1)"
        />
      </div>
    </div>
    <div :class="$style.list">
      <a-spin
        v-for="(data, idx) in commonData"
        :key="idx"
        :spinning="data.loading"
      >
        <div :class="$style.list_item">
          <div
            v-for="(item, idx1) in data.list"
            :key="item.id"
            :class="$style.newsList"
          >
            <div>
              <a-space>
                <a-avatar :size="50" :src="item.user.head_img" />
                <div>
                  <div :class="$style.name">{{ item.user.user_name }}</div>
                  <div :class="$style.time">
                    {{ useFormatTime(item.publish_time) }}
                  </div>
                </div>
              </a-space>
            </div>
            <div
              v-dompurify-html="item.content"
              style="padding-left: 60px"
            ></div>
            <div
              v-if="item.production !== null"
              style="min-height: 110px; padding-left: 60px"
            >
              <a-image-preview-group>
                <a-space :size="[8, 16]" wrap>
                  <a-image
                    v-for="path in item.production"
                    :key="path"
                    :width="100"
                    :src="path.url"
                  />
                </a-space>
              </a-image-preview-group>
            </div>
            <div :class="$style.opt">
              <a-space>
                <div style="cursor: pointer" @click="handleLike(item)">
                  <LikeFilled v-if="item.is_like" :class="$style.opt_icon" />
                  <LikeOutlined v-else :class="$style.opt_icon" />
                  <span>点赞({{ item.like_count }})</span>
                </div>
                <div
                  style="cursor: pointer"
                  @click="openCommentList(idx1, idx)"
                >
                  <MessageFilled :class="$style.opt_icon" />
                  <span>评论({{ item.comment_count }})</span>
                </div>
              </a-space>
            </div>
            <div v-if="item.openComment">
              <div>
                <a-space>
                  <a-input
                    v-model:value="item.commentValue"
                    placeholder="请输入评论"
                    style="width: 380px"
                    allow-clear
                    @pressEnter="handleComment(item)"
                  />
                  <a-button
                    :disabled="!item.commentValue"
                    type="primary"
                    @click="handleComment(item)"
                  >
                    发表
                  </a-button>
                </a-space>
              </div>
              <div :class="$style.comment">
                <div v-for="c in item.commentList" :key="c.comment_id">
                  <CommentItem :item-data="c.comment" />
                </div>
              </div>
            </div>
          </div>
        </div>
      </a-spin>
    </div>
    <a-modal
      v-model:open="openModel"
      title="发布"
      width="30%"
      @ok="handleOk"
      @cancel="handleCancel"
    >
      <div>
        <a-form ref="ruleFormRef" :model="formState" :rules="rules">
          <a-form-item label="内容" name="content">
            <a-textarea
              v-model:value="formState.content"
              placeholder="请输入"
              :rows="3"
              style="width: 500px"
            />
          </a-form-item>
        </a-form>
        <div v-if="imageList.length > 0">
          <a-image-preview-group>
            <a-space :size="[8, 16]" wrap>
              <a-image
                v-for="path in imageList"
                :key="path"
                :width="100"
                :src="path.url"
              />
            </a-space>
          </a-image-preview-group>
        </div>
        <div :class="$style.setting">
          <a-radio-group v-model:value="radioValue" @change="changeRadio">
            <a-radio-button value="a">助写</a-radio-button>
            <a-radio-button value="b">配图</a-radio-button>
          </a-radio-group>
          <div>
            <a-space>
              <a-button type="primary" @click="addImg">添加</a-button>
              <a-button type="primary" @click="reGet">生成</a-button>
              <a-select
                ref="select"
                v-model:value="selectValue"
                style="width: 120px"
                placeholder="请选择"
              >
                <a-select-option
                  v-for="item in options"
                  :key="item"
                  :value="item"
                >
                  {{ item }}
                </a-select-option>
              </a-select>
            </a-space>
          </div>
        </div>
        <div :class="$style.help">
          <a-spin :spinning="contentLoading">
            <a-empty
              v-if="helpText === '' && helpImgUrl === ''"
              :image="simpleImage"
              style="margin-top: 100px"
            />
            <div v-else>
              <div v-if="radioValue === 'a'">
                {{ helpText }}
              </div>
              <div v-if="radioValue === 'b'">
                <a-image
                  v-if="helpImgUrl !== ''"
                  :width="250"
                  :src="helpImgUrl"
                />
              </div>
            </div>
          </a-spin>
        </div>
      </div>
    </a-modal>
  </div>
</template>

<script setup lang="ts">
import { computed, onMounted, reactive, ref } from 'vue';
import { Rule } from 'ant-design-vue/es/form';
import {
  changeLikeStatus,
  createTextOrImg,
  getCommentList,
  getPublishList,
  publishComment,
  publishContent,
} from '@/api';
import { message } from 'ant-design-vue';
import {
  RedoOutlined,
  LikeFilled,
  MessageFilled,
  LikeOutlined,
} from '@ant-design/icons-vue';
import { Empty } from 'ant-design-vue';
import { formateContent } from '@/utils/formate-content';
import { useFormatTime } from '@/utils/hooks';
import CommentItem from '@/components/comment-item.vue';

const simpleImage = Empty.PRESENTED_IMAGE_SIMPLE;

const openModel = ref(false);
const ruleFormRef = ref();
const formState = reactive({
  content: '',
});
const radioValue = ref('a');
const selectValue = ref();
const rules: Record<string, Rule[]> = {
  content: [
    {
      required: true,
      trigger: ['blur', 'change'],
      message: '内容不允许为空',
    },
  ],
};
const options = computed(() => {
  if (radioValue.value !== '') {
    return radioValue.value === 'a' ? ['热情洋溢', '文绉绉'] : ['写实', '卡通'];
  } else {
    return [];
  }
});
const changeRadio = () => {
  selectValue.value = options.value[0];
  helpText.value = '';
  helpImgUrl.value = '';
};
const handleComment = async (item: any) => {
  try {
    const params = {
      articleId: item.article_id_str,
      content: item.commentValue,
    };
    await publishComment(params);
    message.success('评论成功');
    item.commentValue = '';
    await getCommentData(item);
  } catch {
    return false;
  }
};
const openCommentList = (idx1: number, idx: number) => {
  const item = commonData[idx].list[idx1];
  item.openComment = !item.openComment;
  getCommentData(item);
};
const getCommentData = async (item: any) => {
  try {
    const params = {
      articleId: item.article_id_str,
    };
    const { data } = await getCommentList(params);
    if (data.list) {
      item.commentList = data.list;
    }
  } catch {
    return false;
  }
};

const handleLike = async (item: any) => {
  try {
    const params = {
      articleId: item.article_id_str,
      liked: item.is_like !== 1 ? 1 : 0,
    };
    await changeLikeStatus(params);
    if (item.is_like !== 1) {
      item.is_like = 1;
      item.like_count = item.like_count + 1;
    } else {
      item.is_like = 0;
      item.like_count = item.like_count - 1;
    }
  } catch {
    return false;
  }
};
const helpText = ref('');
const helpImgUrl = ref('');
const imageList = ref<{ type: number; url: string }[]>([]);
const contentLoading = ref(false);
const getContent = async (n: number) => {
  try {
    const params = {
      prompt: formState.content,
      style: selectValue.value,
      type: n,
    };
    contentLoading.value = true;
    const res = await createTextOrImg(params);
    if (n === 6) {
      helpText.value = res.data.content;
    } else {
      helpImgUrl.value = res.data.url;
    }
    contentLoading.value = false;
  } catch {
    contentLoading.value = false;
    return false;
  }
};
const addImg = () => {
  if (radioValue.value === 'a') {
    formState.content = helpText.value;
  } else {
    imageList.value.push({
      type: 1,
      url: helpImgUrl.value,
    });
    helpImgUrl.value = '';
  }
};
const reGet = () => {
  if (radioValue.value === 'a') {
    helpText.value = '';
    getContent(6);
  } else {
    helpImgUrl.value = '';
    getContent(1);
  }
};
const handleOk = async () => {
  await ruleFormRef.value.validate();
  try {
    const params = {
      content: formState.content,
    };
    if (imageList.value.length > 0) {
      params['production'] = imageList.value;
    }
    await publishContent(params);
    message.success('发布成功');
    await getList(1);
    handleCancel();
  } catch {
    return false;
  }
};
const handleCancel = () => {
  ruleFormRef.value.resetFields();
  helpText.value = '';
  helpImgUrl.value = '';
  radioValue.value = 'a';
  selectValue.value = null;
  imageList.value = [];
  openModel.value = false;
};
onMounted(() => {
  getList(0);
  getList(1);
  getList(2);
});

type DataType = {
  id: number;
  list: any[];
  loading: boolean;
  current: number;
  total: number;
  pageSize: number;
};
const commonData = reactive<DataType[]>([
  {
    id: 1,
    list: [],
    loading: false,
    current: 1,
    total: 0,
    pageSize: 10,
  },
  {
    id: 2,
    list: [],
    loading: false,
    current: 1,
    total: 0,
    pageSize: 10,
  },
  {
    id: 3,
    list: [],
    loading: false,
    current: 1,
    total: 0,
    pageSize: 10,
  },
]);
const refreshList = (n: number) => {
  getList(n);
};
const handlePageChange = (n: number, flag: number) => {
  commonData[flag].current = n;
  getList(flag);
};
const getList = async (n: number) => {
  try {
    commonData[n].loading = true;
    const params = {
      page: {
        pageNo: commonData[n].current,
        pageSize: commonData[n].pageSize,
      },
      version: `v${n + 1}`,
    };
    const { data } = await getPublishList(params);
    commonData[n].list = data.list.map(v => {
      return {
        ...v,
        openComment: false,
        commentList: [],
        commentValue: '',
        content: formateContent(v.content),
      };
    });
    commonData[n].loading = false;
    commonData[n].current = data.page.page_no;
    commonData[n].total = data.page.total_count;
  } catch {
    return false;
  }
};
</script>

<style module lang="less">
.wapper {
  .top {
    display: flex;
    align-items: center;
    position: relative;
    .page {
      display: flex;
      margin-left: 45px;
      .icon {
        margin-right: 10px;
      }
      &:nth-of-type(n + 2) {
        margin-left: 180px;
      }
    }
  }
  .list {
    display: flex;
    margin-top: 10px;
    .list_item {
      border-radius: 5px;
      border: 1px solid rgba(5, 5, 5, 0.06);
      overflow-y: auto;
      overflow-x: hidden;
      height: 700px;
      width: 500px;
      padding: 10px;
      margin-left: 10px;
      .newsList {
        width: 100%;
        background-color: #ffffff;
        border-radius: 5px;
        margin-top: 10px;
        padding: 10px;
        &:first-child {
          margin-top: 0;
        }
        .opt {
          display: flex;
          justify-content: flex-end;
          line-height: 35px;
          color: #88898e;
          .opt_icon {
            margin-right: 5px;
          }
        }
        .time {
          color: #939393;
          font-size: 13px;
        }
        .comment {
          margin-top: 10px;
          padding-left: 20px;
          max-height: 300px;
          overflow: hidden auto;
        }
      }
    }
  }
}
.setting {
  display: flex;
  justify-content: space-between;
  margin: 10px 0;
}
.help {
  width: 530px;
  height: 300px;
  overflow: hidden auto;
  border-radius: 5px;
  border: 1px solid rgba(5, 5, 5, 0.06);
  padding: 10px;
}
:global {
  .ant-image .ant-image-img {
    border-radius: 8px;
  }
}
</style>
